import os
import uuid
import requests
import time
import random
from create_spec import create_spec
from create import create
from store_image import store_image

BASE_URL = 'https://open.feishu.cn'
# 商品上传多维表格
APP_TOKEN = 'ZbnybBxZPatbNYsmjAvcVk2dnGh'
TABLE_ID = 'tbl8Dl8miTwQHpNA'
APP_ID = 'cli_a89f1ee951f9d00e'
APP_SECRET = 'MfMtAGE2IYX4N6DjvzsPIgC3ZhkSvjgs'
headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer t-g10453geGHZSIQ22Q4VQ7OFHZTGE4FLOP2CKN2RB'
}

token_expire_time = 0

def get_access_token():
    """获取访问令牌"""
    global token_expire_time
    if token_expire_time != 0 and token_expire_time - time.time() > 10:
        # print(f"令牌有校, 跳过令牌刷新, token_expire_time = {int(token_expire_time)}, current_time = {int(token_expire_time)}")
        return

    url = f'{BASE_URL}/open-apis/auth/v3/tenant_access_token/internal'
    data = {
        'app_id': APP_ID,
        'app_secret': APP_SECRET
    }
    print('POST', url)
    response = requests.post(url, json=data)
    if response.status_code == 200 and response.json().get('code') == 0:
        expire = response.json().get('expire')
        token_expire_time = expire + time.time()
        # print(f"获取访问令牌成功: expire = {response.json().get('expire')}s")
        access_token = response.json().get('tenant_access_token')
        if access_token:
            headers['Authorization'] = f'Bearer {access_token}'
        else:
            print("get_access_token failed")
            raise SystemExit('获取访问令牌失败')
    else:
        print(f"获取访问令牌失败: {response.status_code}, {response.text}")
        return None

def build_url(endpoint):
    """构建API URL"""
    return f'{BASE_URL}/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/{endpoint}'

def parse_product_info(item):
    """解析商品信息"""
    record_id = item['record_id']
    fields = item['fields']
    
    if '商品名称' not in fields or not fields['商品名称'] or len(fields['商品名称']) == 0:
        return {}

    # 提取商品信息
    product_info = {
        'record_id': record_id,
        'product_name': fields['商品名称'][0]['text'],
        'original_price': fields['划线价(元)'],
        'product_desc': fields['商品描述']['value'][0]['text'],
        'product_category': fields['商品分类'],
        'group_price': round(fields['团购价(元)']['value'][0], 1),
        'spec1_name': fields['商品规格1-名称'][0]['text'],
        'spec1_value': fields['商品规格1-值'][0]['text'],
        'spec2_name': fields['商品规格2-名称'][0]['text'],
        'spec2_value': fields['商品规格2-值'][0]['text'],
        'images': [img['url'] for img in fields['商品图片']],
        'spec1_images': [img['url'] for img in fields.get('商品规格1-图片', [])],
        'spec1_image': fields['商品规格1-图片'][0]['url'] if fields.get('商品规格1-图片') and len(fields['商品规格1-图片']) > 0 else None,
        'quantitys': fields['库存'][0]['text'],
    }
    
    return product_info

def print_product_info(product_info):
    """打印商品信息"""
    print(f"\n记录ID: {product_info['record_id']}")
    print(f"商品名称: {product_info['product_name']}")
    print(f"划线价: {product_info['original_price']}元")
    print(f"商品描述: {product_info['product_desc']}")
    print(f"商品分类: {product_info['product_category']}")
    print(f"团购价: {product_info['group_price']}元")
    
    for img_url in product_info['images']:
        print(f"商品图片URL: {img_url}")
        
    print(f"规格1 ({product_info['spec1_name']}): {product_info['spec1_value']}")
    print(f"规格1图片URL: {product_info['spec1_image']}")
    print(f"规格2 ({product_info['spec2_name']}): {product_info['spec2_value']}")
    print(f"库存: {product_info['quantitys']}")

def replace_image_url(product_info, dir_name):
    # 下载图片
    for index, img_url in enumerate(product_info['images']):
        if not img_url:
            continue
        img_path = download_image(img_url, dir_name)
        if img_path:
            # 上传图片
            response_url = store_image(img_path)
            if response_url:
                # 替换图片URL
                product_info['images'][index] = response_url
            sleep_random()

    # 下载图片
    if not product_info['spec1_image']:
        return product_info
    img_path = download_image(product_info['spec1_image'], dir_name)
    if img_path:
        # 上传图片
        response_url = store_image(img_path)
        if response_url:
            # 替换图片URL
            product_info['spec1_image'] = response_url
        sleep_random()

    # print(f"替换后的商品信息: {product_info}")
    return product_info

def download_image(url, dir_name='images'):
    get_access_token()

    print('GET', url)
    response = requests.get(url, headers={'Authorization': headers["Authorization"]})
    if response.status_code == 200:
        # 生成本地文件名
        file_name = f"{uuid.uuid4().hex}.jpg"
        file_path = f'{dir_name}/{file_name}'  # 保存到images目录下
        
        # 确保images目录存在
        os.makedirs(dir_name, exist_ok=True)
        
        # 保存图片到本地
        with open(file_path, 'wb') as f:
            f.write(response.content)
        
        print(f"图片下载成功并保存到: {file_path}")
        return file_path
    else:
        print(f"图片下载失败, 状态码: {response.status_code}")
        return None

def row_to_json(row):
    good_ruler_2_value = row['spec2_value'].strip()
    good_ruler_2_value_list = [item.strip() for item in good_ruler_2_value.replace('\n', ',').split(',') if item.strip()]
    good_ruler_2_quantity = str(row.get('quantitys', '')).strip() if row.get('quantitys') is not None else ''
    good_ruler_2_quantity_list = [item.strip() for item in good_ruler_2_quantity.replace('\n', ',').split(',') if item.strip()]
    spec_map_for_create = {
        row['spec1_name']: [row['spec1_value']],
        row['spec2_name']: good_ruler_2_value_list
    }
    # print('spec_map_for_create', spec_map_for_create)
    create_spec_res = create_spec(spec_map_for_create)
    if 'result' not in create_spec_res:
        raise ValueError("create_spec 出错", spec_map_for_create, create_spec_res)
    create_spec_response = create_spec_res['result']
    # print('create_spec_response', create_spec_response)
    
    spec_id_spec_dto_map = {}
    for _, specs in create_spec_response['spec_map'].items():
        for spec in specs:
            spec_id_spec_dto_map[str(spec['spec_id'])] = {
                'spec_id': spec['spec_id'],
                'name': spec['name'],
                'parent_name': spec['parent_name']
            }
    # print('spec_id_spec_dto_map', spec_id_spec_dto_map)

    spec_map = [
        {
            'value': row['spec1_name'],
            'list': [
                {
                    'name': row['spec1_value'],
                    'thumb_url': [],
                },
            ],
        },
        {
            'value': row['spec2_name'],
            'list': [{'name': name} for name in good_ruler_2_value_list],
        }
    ]
    # print('spec_map', spec_map)
    
    sku_list = []
    first_category_specs = create_spec_response['spec_map'][row['spec1_name']]
    second_category_specs = create_spec_response['spec_map'][row['spec2_name']]
    if first_category_specs and second_category_specs:
        # 生成组合
        for first_spec in first_category_specs:
            for index, second_spec in enumerate(second_category_specs):
                quantity = int(good_ruler_2_quantity_list[index]) if good_ruler_2_quantity_list and len(good_ruler_2_quantity_list) > index and good_ruler_2_quantity_list[index] is not None else 10000000
                sku_list.append({
                    'sku_material_id': None,
                    'thumb_url': row['spec1_image'] if row['spec1_image'] else '',
                    # "thumb_url": "",
                    'price': int(row["group_price"] * 100),
                    'quantity_type': 1 if quantity == 10000000 else 0,
                    'quantity': quantity,
                    'remain_quantity': quantity,
                    'reserve_quantity': 0,
                    'sold_quantity': 0,
                    'spec_id_list': [first_spec['spec_id'], second_spec['spec_id']],
                    'spec_list': [
                        {
                            'spec_id': first_spec['spec_id'],
                            'name': first_spec['name'],
                            'parent_name': first_spec['parent_name']
                        },
                        {
                            'spec_id': second_spec['spec_id'],
                            'name': second_spec['name'],
                            'parent_name': second_spec['parent_name']
                        }
                    ],
                    'cost_price': -1,
                    'total_quantity': quantity,
                })
    else:
        raise ValueError("规格分类数量不足，无法进行组合。至少需要两个分类。")

    # print('sku_list', sku_list)

    return {
        "goods_name": row["product_name"].replace('\n', ' ').replace('\r\n', ' ').strip(),
        'goods_price': 0,
        "market_price": int(row["original_price"] * 100),
        'specification': '',
        'quantity_type': 1,
        'quantity': 70000000,
        'sold_quantity': 0,
        'remain_quantity': 70000000,
        'reserve_quantity': 0,
        'description': row["product_desc"],
        "category_id": row["product_category"],
        'image_urls': row["images"],
        # 'image_urls': [
        #     'https://commimg.pddpic.com/monica/2025-03-29/883747ab-4fd2-49e2-b3b9-bf2c360e0cd9.png.suffix.png'
        # ],
        'labels': [],
        'sku_list': sku_list,
        'spec_map': spec_map,
        'spec_id_spec_dto_map': spec_id_spec_dto_map,
        'video_list': [],
        # 'goods_cover': 'https://commimg.pddpic.com/monica/2025-03-29/883747ab-4fd2-49e2-b3b9-bf2c360e0cd9.png.suffix.png',
        'goods_cover': row["images"][0] if row["images"] else '',
        'goods_material_type': 0,
        'goods_info_sync_status': 0,
        'has_quantity_sync_relation': False,
        'has_sold_quantity': False,
        'weight': 0,
        'sign': 'FEE79E11C4877EF7A9DB8C9C53FB1B3D',
        'signVersion': 'sv1',
        'timestamp': int(time.time() * 1000)
    }

def sleep_random():
    random_value = random.uniform(3, 5)
    print(f"等待{random_value:.2f}s ...")
    time.sleep(random_value)

def search_records(view_id="vewERcL6jc"):
    get_access_token()

    """查询记录"""
    # 该接口用于查询数据表中的现有记录，单次最多查询 500 行记录，支持分页获取
    # curl -i -X POST 'https://open.feishu.cn/open-apis/bitable/v1/apps/ZbnybBxZPatbNYsmjAvcVk2dnGh/tables/tbl8Dl8miTwQHpNA/records/search' \
    # -H 'Content-Type: application/json' \
    # -H 'Authorization: Bearer t-g10453dsM72G3PJPALNVKMEPNSVQMK7RZGYIKDPX' \
    # -d '{
    # 	"automatic_fields": false,
    # 	"view_id": "vewERcL6jc"
    # }'

    # 分页大小。最大值为 500
    page_size = 500
    url = build_url(f'records/search?page_size={page_size}')
    data = {
        "automatic_fields": False,
        "filter": {
            "conditions": [
                {
                    "field_name": "是否添加",
                    "operator": "doesNotContain",
                    "value": [
                        "是", "无需添加"
                    ]
                }
            ],
            "conjunction": "and"
        },
        "view_id": view_id
    }
    
    print('POST', url)
    response = requests.post(url, headers=headers, json=data)
    if response.status_code == 200:
        # print(f"records_search_url 请求成功, response = {response.json()}")
        response_data = response.json()
        if response_data.get('code') == 0:
            return response_data.get('data', {})
        else:
            print(f"查询失败，错误信息: {response_data.get('msg')}")
    else:
        print(f"records_search_url 请求失败, response = {response.json()}")
    return None

def update_records(record_ids):
    get_access_token()

    """更新多条记录"""
    # 更新数据表中的多条记录，单次调用最多更新 1,000 条记录
    # curl -i -X POST 'https://open.feishu.cn/open-apis/bitable/v1/apps/ZbnybBxZPatbNYsmjAvcVk2dnGh/tables/tbl8Dl8miTwQHpNA/records/batch_update' \
    # -H 'Content-Type: application/json' \
    # -H 'Authorization: Bearer t-g10453dsM72G3PJPALNVKMEPNSVQMK7RZGYIKDPX' \
    # -d '{
    # 	"records": [
    # 		{
    # 			"fields": {
    # 				"是否添加": true
    # 			},
    # 			"record_id": "recHAkaPPw"
    # 		}
    # 	]
    # }'

    # 将record_ids转换为records格式
    records = [
        {
            "fields": {
                "是否添加": "是"
            },
            "record_id": record_id
        }
        for record_id in record_ids
    ]
    url = build_url('records/batch_update')
    data = {"records": records}

    print('POST', url)
    response = requests.post(url, headers=headers, json=data)
    if response.status_code == 200:
        print(f"records_batch_update_url 请求成功, response = {response.json()}")
        response_data = response.json()
        if response_data.get('code') == 0:
            print(f"成功更新 {len(record_ids)} 条记录")
            return True
        else:
            print(f"更新失败, 错误信息: {response_data.get('error')}")
            raise SystemExit('更新在线表格失败')
    else:
        print(f"records_batch_update_url 请求失败, response = {response.json()}")
        raise SystemExit('更新在线表格失败')

def main():
    # 查询记录
    data = search_records()
    if data:
        items = data.get('items', [])
        total = data.get('total', 0)
        print(f"共找到 {total} 条记录")
        
        # 初始化计数器
        added_count = 0
        # 存储成功添加的record_id
        success_record_ids = []
        dir_name = 'images_' + str(random.randint(100, 999))
        for index, item in enumerate(items):
            # 检查是否添加字段
            if '是否添加' in item['fields'] and item['fields'].get('是否添加') in ['是', '无需添加']:
                print(f"跳过已添加/无需添加的商品: {item['record_id']}")
                continue

            product_info = parse_product_info(item)
            if product_info == {}:
                print(f"解析商品信息为空: {item['record_id']}")
                continue

            product_info = replace_image_url(product_info, dir_name)
            print_product_info(product_info)

            goods_name = product_info['product_name']
            print(f"开始创建商品{index+1}: {goods_name}")
        
            json_data = row_to_json(product_info)
            sleep_random()
            create_resposne = create(json_data)
            if create_resposne['success'] and create_resposne['result']['success']:
                print(f'创建成功{index+1}: {goods_name}')
                success_record_ids.append(item['record_id'])
                added_count += 1
                update_records([item['record_id']])
            else:
                print(f'创建失败{index+1}: {goods_name}, {create_resposne}')
            
            print('\n')
            sleep_random()
        
        print(f"成功添加商品数量: {added_count}")

        # 更新记录
        # if success_record_ids:
        #     update_records(success_record_ids)

        # 删除图片文件夹
        if os.path.exists(dir_name):
            # 删除文件夹内的所有文件
            for file_name in os.listdir(dir_name):
                file_path = os.path.join(dir_name, file_name)
                os.remove(file_path)
            # 删除空文件夹
            os.rmdir(dir_name)
            print(f"已删除图片下载文件夹: {dir_name}")

if __name__ == '__main__':
    main()
    input("按任意键退出...")